Skip to content

[libc++] Remove assertions from <string_view> that are unreachable #148598

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

philnik777
Copy link
Contributor

When assertions are enabled it is impossible to construct a string_view which contains a null pointer and a non-zero size, so assertions where we check for that on an already constructed string_view are unreachable.

@philnik777 philnik777 marked this pull request as ready for review July 14, 2025 13:46
@philnik777 philnik777 requested a review from a team as a code owner July 14, 2025 13:46
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Jul 14, 2025
@philnik777 philnik777 requested review from var-const and removed request for a team July 14, 2025 13:47
@llvmbot
Copy link
Member

llvmbot commented Jul 14, 2025

@llvm/pr-subscribers-libcxx

Author: Nikolas Klauser (philnik777)

Changes

When assertions are enabled it is impossible to construct a string_view which contains a null pointer and a non-zero size, so assertions where we check for that on an already constructed string_view are unreachable.


Full diff: https://github.com/llvm/llvm-project/pull/148598.diff

1 Files Affected:

  • (modified) libcxx/include/string_view (-8)
diff --git a/libcxx/include/string_view b/libcxx/include/string_view
index 861187c0640e1..4a85c73733023 100644
--- a/libcxx/include/string_view
+++ b/libcxx/include/string_view
@@ -500,7 +500,6 @@ public:
   // find
   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
   find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT {
-    _LIBCPP_ASSERT_NON_NULL(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
     return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s.data(), __pos, __s.size());
   }
 
@@ -524,7 +523,6 @@ public:
   // rfind
   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
   rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT {
-    _LIBCPP_ASSERT_NON_NULL(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
     return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s.data(), __pos, __s.size());
   }
 
@@ -549,7 +547,6 @@ public:
   // find_first_of
   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
   find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT {
-    _LIBCPP_ASSERT_NON_NULL(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr");
     return std::__str_find_first_of<value_type, size_type, traits_type, npos>(
         data(), size(), __s.data(), __pos, __s.size());
   }
@@ -575,7 +572,6 @@ public:
   // find_last_of
   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
   find_last_of(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT {
-    _LIBCPP_ASSERT_NON_NULL(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr");
     return std::__str_find_last_of<value_type, size_type, traits_type, npos>(
         data(), size(), __s.data(), __pos, __s.size());
   }
@@ -601,8 +597,6 @@ public:
   // find_first_not_of
   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
   find_first_not_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT {
-    _LIBCPP_ASSERT_NON_NULL(
-        __s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr");
     return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(
         data(), size(), __s.data(), __pos, __s.size());
   }
@@ -628,8 +622,6 @@ public:
   // find_last_not_of
   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
   find_last_not_of(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT {
-    _LIBCPP_ASSERT_NON_NULL(
-        __s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr");
     return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(
         data(), size(), __s.data(), __pos, __s.size());
   }

@ldionne
Copy link
Member

ldionne commented Jul 14, 2025

I'd like @var-const to have a look cause we did encounter some issues with this check in string_view when we deployed it IIRC.

@var-const
Copy link
Member

Thanks for pinging! Sorry I'm just now getting to this.

@ldionne I believe the issues you probably have in mind were in span's constructor, not string_view.

@philnik777 It's not 100% true that these are unreachable: https://godbolt.org/z/7sxTez18q. I can't recall why the constructor check is not enabled in the C++11 mode (it seems to ring a very vague bell, but maybe I'm confusing it with something). Doing a little archaeology, it seems like it was that way from the very first implementation by Marshal. @ldionne Do you have any recollection on this, perhaps?

I'd be on board with removing the version check in the constructor's assertion (assuming there's no good reason to keep it, at least now) which will clear the way for the change in this patch. But perhaps there's a reason to keep the version check?

Copy link
Member

@var-const var-const left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's figure out what to do about the C++11 mode (otherwise LGTM).

@philnik777
Copy link
Contributor Author

@var-const This was most likely done because C++11 didn't allow anything in the constructor body in C++11. Clang accepts it as an extension now, so we can simply enable the asserts in C++11 mode for Clang.

@var-const
Copy link
Member

Clang accepts it as an extension now, so we can simply enable the asserts in C++11 mode for Clang.

SGTM, can you please do it in this patch as well?

@philnik777 philnik777 force-pushed the string_view_remove_asserts branch from b6c6104 to d832e1f Compare August 7, 2025 07:28
Copy link

github-actions bot commented Aug 7, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@philnik777
Copy link
Contributor Author

@var-const are you happy with this now?

Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with minor comments. I spoke with @var-const just now and he was fine with the patch as well (but can chime in if needed).

@philnik777 philnik777 force-pushed the string_view_remove_asserts branch from d832e1f to 3897132 Compare August 12, 2025 08:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants